/* 

字典 wordList 中从单词 beginWord 和 endWord 的 转换序列 是一个按下述规格形成的序列：

序列中第一个单词是 beginWord 。
序列中最后一个单词是 endWord 。
每次转换只能改变一个字母。
转换过程中的中间单词必须是字典 wordList 中的单词。
给你两个单词 beginWord 和 endWord 和一个字典 wordList ，找到从 beginWord 到 endWord 的 最短转换序列 中的 单词数目 。如果不存在这样的转换序列，返回 0。

 
示例 1：

输入：beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"]
输出：5
解释：一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog", 返回它的长度 5。
示例 2：

输入：beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log"]
输出：0
解释：endWord "cog" 不在字典中，所以无法进行转换。

来源：力扣（LeetCode）
链接：https://leetcode-cn.com/problems/word-ladder
著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。

*/

/**
 * @param {string} beginWord
 * @param {string} endWord
 * @param {string[]} wordList
 * @return {number}
 */

// 无权图BFS遍历
var ladderLength = function (beginWord, endWord, wordList) {
    const isSimilar = (a, b) => {
        let diff = 0;
        // 有提示可知每个单词的长度一致
        for (let i = 0; i < a.length; i++) {
            //if (a.charAt(i) !== b.charAt(i)) diff++;
            if (a[i] !== b[i]) diff++;
            if (diff > 1) return false;
        }
        return true;
    }

    const queue = [beginWord];
    const index = wordList.indexOf(beginWord);
    if (index !== -1) wordList.splice(index, 1);
    let res = 2;
    while (queue.length) {
        let size = queue.length;
        while (size--) {
            const front = queue.shift();
            for (let i = 0; i < wordList.length; i++) {
                if (!isSimilar(front, wordList[i])) continue;
                if (wordList[i] === endWord) {
                    return res;
                } else {
                    queue.push(wordList[i]);
                    wordList.splice(i, 1);
                    // 注意还学要 i--，这是因为用splice删掉i处的元素后，i+1处的元素会移动到i处，所以还需要遍历一次i处而不是直接到i+1处
                    i--;
                }
            }
        }
        res++;
    }
    return 0;
};